#include <iostream>
#include <pthread.h>
#include <cstring>
#include <string>
#include <unistd.h>
#include "GardLock.hpp"
#include "Thread.hpp"
using namespace std;

int tickets = 2000;
// pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; // 该形式下的初始化不需要销毁
pthread_mutex_t mutex;

// 自动抢票逻辑
void threadRoutine(void *args)
{
    string name = static_cast<const char *>(args);
    while (true) 
    {
        // pthread_mutex_lock(&mutex);
        { //////////////////////////////// 临界区
            GardLock gard(&mutex); // 自动锁，构造对象时自动锁，出了对应的作用域后自动开锁
            if (tickets > 0)
            {
                // 模拟票的查找过程
                usleep(2000); 
                cout << name << " get tickets: " << tickets-- << endl;
                // pthread_mutex_unlock(&mutex);
            }
            else
            {
                // pthread_mutex_unlock(&mutex);
                break;
            }
        } ///////////////////////////////// 临界区
        // 模拟票进数据库的过程
        usleep(2000);
    } 
}

int main()
{
    thread th1(1, threadRoutine, (void*)"thread 1"); // 函数名就是指针变量
    thread th2(2, threadRoutine, (void*)"thread 2");
    thread th3(3, threadRoutine, (void*)"thread 3");
    thread th4(4, threadRoutine, (void*)"thread 4");

    th1.run();
    th2.run();
    th3.run();
    th4.run();

    //sleep(100);
    th1.join();
    th2.join();
    th3.join();
    th4.join();
    // pthread_t th[4];
    // pthread_mutex_init(&mutex, nullptr);

    // for (int i = 0; i < 4; i++)
    // {
    //     char *buff = new char[64];
    //     snprintf(buff, 64, "thread-%d", i);
    //     pthread_create(&th[i], nullptr, threadRoutine, (void *)buff);
    // }

    // for (int i = 0; i < 4; i++)
    // {
    //     pthread_join(th[i], nullptr);
    // }

    pthread_mutex_destroy(&mutex);
    return 0;
}

// 线程不能既是分离，又是joinable
// void* threadrun(void* args)
// {
//     pthread_detach(pthread_self());
//     string name = static_cast<const char*>(args);
//     int cnt = 5;
//     while(cnt)
//     {
//         cout << name << "is running ..." << "cnt :" << cnt-- << endl;
//         sleep(1);
//     }
// }

// int main()
// {
//     pthread_t th;
//     pthread_create(&th, nullptr, threadrun, (void*)"thread 1");

//     sleep(1);
//     int n = pthread_join(th, nullptr);
//     if(n != 0)
//     {
//         cerr << "errno : " << n << strerror(n) << endl;
//         cout << "thread not need to be join" << endl;
//     }

//     //cout << "pthread_join succeed..." << endl;
//     return 0;
// }